package com.ccp.dev.qbdms.service;

import static com.ccp.dev.extend.util.ServiceUtil.getBasePath;
import static com.ccp.dev.qbdms.util.TikaUtils.replaceBlank;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ccp.dev.core.basic.base.BaseService;
import com.ccp.dev.core.basic.response.ReturnCode;
import com.ccp.dev.core.basic.web.query.QueryFilter;
import com.ccp.dev.core.poi.excel.Excel;
import com.ccp.dev.core.util.BeanUtils;
import com.ccp.dev.core.util.StringPool;
import com.ccp.dev.core.util.StringUtil;
import com.ccp.dev.extend.model.ExtendSysFile;
import com.ccp.dev.qbdms.consts.ZhiLiangConst;
import com.ccp.dev.qbdms.dao.WQbdQualityAnalysisReportDao;
import com.ccp.dev.qbdms.model.SysOrgDeploy;
import com.ccp.dev.qbdms.model.WQbdQualityAnalysisReport;
import com.ccp.dev.qbdms.model.WQbdQualityKnow;
import com.ccp.dev.qbdms.model.es.WQbdQualityAnalysisReportES;
import com.ccp.dev.qbdms.repository.WQbdQualityAnalysisReportRepository;
import com.ccp.dev.qbdms.util.BaseUtil;
import com.ccp.dev.qbdms.util.HttpSendUtil;
import com.ccp.dev.qbdms.util.ProjectUUIDUtils;
import com.ccp.dev.qbdms.util.ReadAttachmentUtil;
import com.ccp.dev.qbdms.util.TikaUtils;
import com.ccp.dev.system.model.Dictionary;
import com.ccp.dev.system.model.SysFile;
import com.ccp.dev.system.service.DictionaryService;
import com.ccp.dev.system.service.SysFileService;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Resource;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;


/**
 * 质量综合分析报告
 信息操作服务类
 *
 * @author mi
 * @date 2020-06-22 14:16:42
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class WQbdQualityAnalysisReportService extends BaseService<WQbdQualityAnalysisReport> {

    @Resource
    private WQbdQualityAnalysisReportDao dao;
    @Resource
    private SysOrgDeployService sysOrgDeployService;

    @Resource
    SysFileService sysFileService;
    @Resource
    DictionaryService dictionaryService;

    @Resource
    WQbdQualityAnalysisReportRepository wQbdQualityAnalysisReportRepository;

    public HSSFWorkbook exportExcel(Excel excel,QueryFilter queryFilter){
    List<WQbdQualityAnalysisReport> dataList = this.dao.queryAll(queryFilter);
        int startRow = 1;
        //给每一个单元格赋值
        for (WQbdQualityAnalysisReport data : dataList) {
        excel.cell(startRow, 0).value(data.getId());
        //excel.cell(startRow, 1).value(data.getMc());
        //可在赋值时，根据需求进行格式化
        //excel.cell(startRow, 2).value(DateFormatUtil.formatDate(data.getRq()));
        //excel.cell(startRow, 3).value(data.getSj());
        //excel.cell(startRow, 4).value(data.getTenantId());
        startRow++;
        }
        return excel.getWorkBook();
    }

    /**
     * 集团下发 质量综合分析报告 修改数据状态
     * @param idStr 主键
     * @return 操作结果或者错误原因
     */
    public String xf(String idStr) {

        return ReturnCode.SUCCESS.getMsg();
    }

    public int updateList(List<WQbdQualityAnalysisReport> updateList,String status) {
        int result=0;
        for(WQbdQualityAnalysisReport updateEntity:updateList){
            if(status!=null){updateEntity.setStatus(status);}
            result+=update(updateEntity);
        }
        return result;
    }
//------------------------------------------es接口------------------------------------------------------------------------
    /**
     * 保存
     * @param wQbdQualityAnalysisReport
     */
    public  void  addAndupdateES(WQbdQualityAnalysisReport wQbdQualityAnalysisReport){
        WQbdQualityAnalysisReportES reportES = new WQbdQualityAnalysisReportES();
        BeanUtils.copyNotNullProperties(reportES,wQbdQualityAnalysisReport);
        String attachmentUrl = reportES.getAttachmentUrl();
        Optional<WQbdQualityAnalysisReportES> repository = wQbdQualityAnalysisReportRepository.findById(wQbdQualityAnalysisReport.getId());
        //新增
        if( ObjectUtils.isEmpty(repository)){
            if (StringUtil.isNotEmpty(attachmentUrl)){
                List<Map<String, String>> listObjectFir = (List<Map<String, String>>) JSONArray.parse(attachmentUrl);
                WQbdQualityAnalysisReportES analysisReportES = getFile(listObjectFir, reportES);
                wQbdQualityAnalysisReportRepository.save(analysisReportES);
            }
        }else {
            //编辑  判断是否更换了附件
            if (StringUtil.isNotEmpty(attachmentUrl)){
                List<Map<String, String>> listObjectFir = (List<Map<String, String>>) JSONArray.parse(attachmentUrl);
                WQbdQualityAnalysisReportES analysisReportES = getFile(listObjectFir,reportES);
                wQbdQualityAnalysisReportRepository.save(analysisReportES);
            }

        }
    }


    public  WQbdQualityAnalysisReportES  getFile(List<Map<String, String>> list,WQbdQualityAnalysisReportES reportES){
        String fileNames="";
        String texts="";
        String basePath = getBasePath();
        for (Map<String, String> stringStringMap : list) {
            String fileName =stringStringMap.get("fileName");
            SysFile sysFile = sysFileService.getOneById(stringStringMap.get("fileId"));
            if (BeanUtils.isNotEmpty(sysFile)) {
                fileNames+=fileName;
                String path = basePath + File.separator + sysFile.getFilePath();
                String text = TikaUtils.fileToString(path);
                texts+=text;
            }
        }
        reportES.setAttachmentFileName(fileNames);
        reportES.setAttachmentContent(texts);
        return  reportES;
    }


    /**
     * 删除接口
     * @param id
     */
    public void deleteES(String id){
        String[] ids=id.split(",");
        for (String s : ids) {
            wQbdQualityAnalysisReportRepository.deleteById(s);
        }
    }
    @Resource
    ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 高级检索
     * @param queryFilter
     * @return
     */
    public List<WQbdQualityAnalysisReport> queryES(QueryFilter queryFilter){
        String content=queryFilter.get("content").toString();
        String secret=queryFilter.get("secret").toString();
        //为方便测试查看数据，暂时屏蔽数据隔离，后期需要去掉此行
        String belongdeptname=queryFilter.get("belongdeptname").toString().replace("%","");
        Object filldeptid = queryFilter.get("filldeptid");
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if(!ObjectUtils.isEmpty(filldeptid)){
            String filldeptids = filldeptid.toString();
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("filldeptid", filldeptids);
            boolQueryBuilder.must(termQueryBuilder);
        }
        Object filldeptHospitalId= queryFilter.get("filldeptHospitalId");
        if(!ObjectUtils.isEmpty(filldeptHospitalId)){
            String filldeptHospitalIds = filldeptHospitalId.toString();
            TermQueryBuilder termQuery = QueryBuilders.termQuery("filldeptHospitalId", filldeptHospitalIds);
            boolQueryBuilder.must(termQuery);
        }
        Object reportStatus= queryFilter.get("reportStatus");
        if(!ObjectUtils.isEmpty(reportStatus)){
            String reportStatus1 = reportStatus.toString().replaceAll("\'", "");
            String[] split = reportStatus1.split(",");
            TermsQueryBuilder termQuery = QueryBuilders.termsQuery("reportStatus", split);
            boolQueryBuilder.must(termQuery);
        }Object xf= queryFilter.get("xf");
        if(!ObjectUtils.isEmpty(xf)){
            ExistsQueryBuilder existsQueryBuilder = QueryBuilders.existsQuery("status");
            boolQueryBuilder.must(existsQueryBuilder);
            ExistsQueryBuilder existsQueryBuilder2 = QueryBuilders.existsQuery("xfdataId");
            boolQueryBuilder.must(existsQueryBuilder2);
        }Object createByGroup= queryFilter.get("createByGroup");
        if(!ObjectUtils.isEmpty(createByGroup)){
            ExistsQueryBuilder existsQuery = QueryBuilders.existsQuery("status");
            boolQueryBuilder.must(existsQuery);
            ExistsQueryBuilder existsQueryBuilder2 = QueryBuilders.existsQuery("xfdataId");
            boolQueryBuilder.mustNot(existsQueryBuilder2);
        }
        Object status= queryFilter.get("status");
        if(!ObjectUtils.isEmpty(status)){
            String status1 = status.toString();
            TermQueryBuilder termQuery = QueryBuilders.termQuery("status", status1);
            boolQueryBuilder.must(termQuery);
        }
        //为方便测试查看数据，暂时屏蔽数据隔离，后期需要去掉此行
        QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("belongdeptname", belongdeptname+"*");
        QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(content);
//        .field("attachmentContent")
        //为方便测试查看数据，暂时屏蔽数据隔离，后期需要去掉此行
        boolQueryBuilder.must(queryBuilder).must(queryStringQueryBuilder);
//        boolQueryBuilder.must(queryStringQueryBuilder);
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        //小于等于
        QueryBuilders.rangeQuery("secret").lte(secret);
        nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("year").order(SortOrder.DESC));
        nativeSearchQueryBuilder.withPageable(PageRequest.of(queryFilter.getPageBean().getThisPageFirstElementNumber()-1,queryFilter.getPageBean().getPageSize()));
        System.err.println(nativeSearchQueryBuilder.build().getQuery().toString());



        Page<WQbdQualityAnalysisReportES> list = wQbdQualityAnalysisReportRepository.search(nativeSearchQueryBuilder.build());
        List<WQbdQualityAnalysisReportES> list1=list.getContent();
        List<WQbdQualityAnalysisReport> list2 = new ArrayList();
        list1.stream().forEach(n->{
            WQbdQualityAnalysisReport wQbdQualityAnalysisReport = JSONObject.parseObject(com.alibaba.fastjson.JSONObject.toJSONString(n), WQbdQualityAnalysisReport.class);
            list2.add(wQbdQualityAnalysisReport);
        });
        List<Dictionary> dicList = dictionaryService.getDicByNodeKey("mj", false);

        list2.stream().forEach(m->{
            dicList.forEach(a->{
                if(a.getItemValue().equals(m.getSecret())){
                    m.setSecretStr(a.getItemName());
                }
            });
        });
        return list2;
    }



    public int queryESCount(QueryFilter queryFilter){
        String content=queryFilter.get("content").toString();
        String secret=queryFilter.get("secret").toString();
        //为方便测试查看数据，暂时屏蔽数据隔离，后期需要去掉此行
        String belongdeptname=queryFilter.get("belongdeptname").toString().replace("%","");
        Object filldeptid = queryFilter.get("filldeptid");
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if(!ObjectUtils.isEmpty(filldeptid)){
            String filldeptids = filldeptid.toString();
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("filldeptid", filldeptids);
            boolQueryBuilder.must(termQueryBuilder);
        }
        Object filldeptHospitalId= queryFilter.get("filldeptHospitalId");
        if(!ObjectUtils.isEmpty(filldeptHospitalId)){
            String filldeptHospitalIds = filldeptHospitalId.toString();
            TermQueryBuilder termQuery = QueryBuilders.termQuery("filldeptHospitalId", filldeptHospitalIds);
            boolQueryBuilder.must(termQuery);
        }
        Object reportStatus= queryFilter.get("reportStatus");
        if(!ObjectUtils.isEmpty(reportStatus)){
            String reportStatus1 = reportStatus.toString().replaceAll("\'", "");
            String[] split = reportStatus1.split(",");
            TermsQueryBuilder termQuery = QueryBuilders.termsQuery("reportStatus", split);
            boolQueryBuilder.must(termQuery);
        }Object xf= queryFilter.get("xf");
        if(!ObjectUtils.isEmpty(xf)){
            ExistsQueryBuilder existsQueryBuilder = QueryBuilders.existsQuery("status");
            boolQueryBuilder.must(existsQueryBuilder);
            ExistsQueryBuilder existsQueryBuilder2 = QueryBuilders.existsQuery("xfdataId");
            boolQueryBuilder.must(existsQueryBuilder2);
        }Object createByGroup= queryFilter.get("createByGroup");
        if(!ObjectUtils.isEmpty(createByGroup)){
            ExistsQueryBuilder existsQuery = QueryBuilders.existsQuery("status");
            boolQueryBuilder.must(existsQuery);
            ExistsQueryBuilder existsQueryBuilder2 = QueryBuilders.existsQuery("xfdataId");
            boolQueryBuilder.mustNot(existsQueryBuilder2);
        }
        Object status= queryFilter.get("status");
        if(!ObjectUtils.isEmpty(status)){
            String status1 = status.toString();
            TermQueryBuilder termQuery = QueryBuilders.termQuery("status", status1);
            boolQueryBuilder.must(termQuery);
        }
        //为方便测试查看数据，暂时屏蔽数据隔离，后期需要去掉此行
        QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("belongdeptname", belongdeptname+"*");
        QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(content);
//        .field("attachmentContent")
        //为方便测试查看数据，暂时屏蔽数据隔离，后期需要去掉此行
        boolQueryBuilder.must(queryBuilder).must(queryStringQueryBuilder);
//        boolQueryBuilder.must(queryStringQueryBuilder);
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        //小于等于
        QueryBuilders.rangeQuery("secret").lte(secret);
        nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("year").order(SortOrder.DESC));
        nativeSearchQueryBuilder.withPageable(PageRequest.of(queryFilter.getPageBean().getThisPageFirstElementNumber()-1,queryFilter.getPageBean().getPageSize()));
        System.err.println(nativeSearchQueryBuilder.build().getQuery().toString());


        long count = elasticsearchTemplate.count(nativeSearchQueryBuilder.build(), WQbdQualityAnalysisReportES.class);


        return (int) count;
    }
    /**
     * 查询上报流程的业务数据
     *
     * @param id
     * @param tableName
     * @return
     */
    public List<WQbdQualityAnalysisReport> reportList(String id, String tableName) {
        return dao.reportList(id, tableName);
    }

    /**
     * 添加
     * @param  wQbdQualityAnalysisReport
     * @return
     */
    @Override
    public int add(WQbdQualityAnalysisReport wQbdQualityAnalysisReport){
        int result = dao.add(wQbdQualityAnalysisReport);
        if(result!=0){
            addAndupdateES(wQbdQualityAnalysisReport);
        }
        return result;
    }

    /**
     * 更新对象
     * @param wQbdQualityAnalysisReport 要更新的数据对象
     */
    @Override
    public int update(WQbdQualityAnalysisReport wQbdQualityAnalysisReport){
        int result=dao.update(wQbdQualityAnalysisReport);
        if(result!=0){
            addAndupdateES(wQbdQualityAnalysisReport);
        }
        return result;
    }

    /**
     * 根据主表id查询主表加子表数据
     *
     * @param id 主表id
     * @return
     */
    public WQbdQualityAnalysisReport getParentAndChilden(String id) {
        return dao.getParentAndChilden(id);
    }

    /**
     * 保存接口传输的数据
     *
     * @param wQbdQualityAnalysisReportList 主表model,有子表的包含子表数据
     * @return
     */
    public int saveAll(List<WQbdQualityAnalysisReport> wQbdQualityAnalysisReportList,List<ExtendSysFile> extendSysFileList){
        ReadAttachmentUtil.getEntityData(wQbdQualityAnalysisReportList,extendSysFileList);
        int result=0;
        for (WQbdQualityAnalysisReport wQbdQualityAnalysisReport:wQbdQualityAnalysisReportList) {
            if(StringUtil.isEmpty(wQbdQualityAnalysisReport.getFilldeptHospitalId())){
                wQbdQualityAnalysisReport.setBelongdeptname(BaseUtil.getCurrentTenOrgCodePath(wQbdQualityAnalysisReport.getFilldeptid()));
            }else{
                wQbdQualityAnalysisReport.setBelongdeptname(BaseUtil.getCurrentTenOrgCodePath(wQbdQualityAnalysisReport.getFilldeptHospitalId()));
            }
            if (null==dao.getById(wQbdQualityAnalysisReport.getId())){
                result += dao.add(wQbdQualityAnalysisReport);
            }else {
                result += dao.update(wQbdQualityAnalysisReport);
            }
            addAndupdateES(wQbdQualityAnalysisReport);
        }
        return result;
    }

    /**
     * 综合质量分析报告下发接口
     * @param updateList
     * @return
     */
    public boolean reportSend(List<WQbdQualityAnalysisReport> updateList) {
        List<WQbdQualityAnalysisReport> xfList=new ArrayList<>() ;
        xfList.addAll(updateList);
        List<SysOrgDeploy> sysOrgDeployList = sysOrgDeployService.getAllSonDeployMethod();
        List<SysOrgDeploy> failOrgs=new ArrayList<>(sysOrgDeployList.size());
        for (SysOrgDeploy org : sysOrgDeployList) {
            try {
                if (org.getOrgCode()!=null &&!ZhiLiangConst.DEPMETHOND_CENTER.equals(org.getDepmethod())){
                    //分级部署 调用接口
                    String url = org.getUrl();
                    url = url + ZhiLiangConst.URL_API + ZhiLiangConst.URL_VERSION + "wQbdQualityAnalysisReport/reportSend";
                    Map<String, Object> param = new HashMap<>(2);
                    for (WQbdQualityAnalysisReport report:xfList){
                        report.setBelongdeptname(org.getOrgCode()+ StringPool.DOT);
                    }
                    param.put(ZhiLiangConst.API_REPORT_PARA_LIST, xfList);

                    List<ExtendSysFile> fileList = ReadAttachmentUtil.getExtendSysFileList(xfList);
                    if (BeanUtils.isNotEmpty(fileList)) {
                        param.put(ZhiLiangConst.API_REPORT_PARA_LIST_FILE, fileList);
                    }
                    ResponseEntity<JSONObject> response = HttpSendUtil.httpRestClient(url, HttpMethod.POST, param);
                    if (response.getStatusCode() != HttpStatus.OK || (int) response.getBody().get("code") != ReturnCode.SUCCESS.getCode()) {
                        //记录下发失败部门
                        failOrgs.add(org);
                    }
                }else{
                    //集中部署
                    for (WQbdQualityAnalysisReport report:xfList){
                        report.setBelongdeptname(BaseUtil.getCurrentTenOrgCodePath(org.getOrgCode()));
                    }
                    saveSendReport(xfList,null);
                }
            }catch (Exception e){
                e.printStackTrace();
                //记录下发失败部门
                failOrgs.add(org);
            }
        }

        if(failOrgs.size()==0){
            for (WQbdQualityAnalysisReport report:xfList){
                report.setBelongdeptname(BaseUtil.getCurrentTenOrgCodePath(report.getFilldeptid()));
            }
            updateList(updateList, ZhiLiangConst.GROUP_ALREADY_SEND3);
            return true;
        }else {
            System.err.println("综合质量分析报告下发服务异常 -> API接口调用失败!");
            updateList(updateList, ZhiLiangConst.GROUP_FAILURE_SEND2);
            return false;
        }
    }

    /**
     * 保存接收到的 上级下发下来的数据
     * @param sendList
     * @return
     */
    public int saveSendReport(List<WQbdQualityAnalysisReport> sendList,List<ExtendSysFile> extendSysFileList) {
        if(extendSysFileList!=null){
            ReadAttachmentUtil.getEntityData(sendList,extendSysFileList);
        }
        int result=0;
        for (WQbdQualityAnalysisReport report:sendList){
            String xfID=report.getId();
            report.setId(ProjectUUIDUtils.getUUIDFor32());
            report.setXfdataId(xfID);
            if(ZhiLiangConst.GROUP_FAILURE_SEND2.equals(report.getStatus())){
                //下发失败的数据再次下发时判断是否已经接受过数据
                WQbdQualityAnalysisReport xfData=dao.getByXfdataId(report);
                if(xfData!=null){
                    dao.delByXfdataId(report.getXfdataId());
                    deleteES(xfData.getId());
                }
            }
            report.setStatus(ZhiLiangConst.GROUP_ALREADY_SEND3);
            result+=dao.add(report);
            addAndupdateES(report);
            report.setId(xfID);
            report.setXfdataId(null);
        }
        return result;
    }


    /**
     * 根据主键集合批量删除
     * @param id 数据主键数组
     */
    public int delByIdArray(String id) throws Exception{
        int delResult=baseDao.delByIdArray(id.split(","));
        if(delResult>0){
            deleteES(id);
        }
        return delResult;
    }
}
